#ifndef _SYSTEM_
#define _SYSTEM_

#define SYSTEM_SCHEDULE_CLOCK_SPEED 1000
#define system_h
#include <timer.h>
void keyboard();
void suspend_all();
unsigned char inportb(unsigned short _port);
void outportb(unsigned short _port, unsigned char _data);
void outportw(unsigned short _port,unsigned short _data);
extern unsigned long _cpu_eax;
extern unsigned long _cpu_ebx;
extern unsigned long _cpu_ecx;
extern unsigned long _cpu_edx;
extern unsigned long _cpu_esp;
extern unsigned long _cpu_ebp;
extern unsigned long _cpu_esi;
extern unsigned long _cpu_edi;
extern unsigned long _cpu_cs;
extern unsigned long _cpu_ds;
extern unsigned long _cpu_ss;
extern unsigned long _cpu_fs;
extern unsigned long _cpu_gs;
extern unsigned long _cpu_es;
extern unsigned long _cpu_cr0;
extern unsigned long _cpu_cr1;
extern unsigned long _cpu_cr2;
extern unsigned long _cpu_cr3;
extern unsigned long _cpu_espp;
extern unsigned long _cpu_eflags;
#include <type.h>

void __cpu(void);
#define start_of_interrupt()						\
	({	asm("pusha");	\
	})


#define end_of_interrupt()						\
	({	asm("popa");	\
		asm("leave");	\
		asm("iret");			\
	})

unsigned long read_cr0();
void write_cr0(unsigned long);
unsigned long read_cr3();
void write_cr3(unsigned long);
void timer();
void set_page_directory_base(unsigned long);


struct CPU_state	{
	unsigned long eax;//0
	unsigned long ebx;//4
	unsigned long ecx;//8
	unsigned long edx;//12
	unsigned long esi;//16
	unsigned long edi;//20
	unsigned long fs;//24
	unsigned long gs;//28
	unsigned long es;//32
	unsigned long ds;//36
	unsigned long esp;//40
	unsigned long ebp;//44
	unsigned long flags;//48
};


typedef struct CPU_state CPU_state;


void show_state(CPU_state *state);

#define NAMEL 20
#define MAXPIPES 8

struct pipe_list	{
	struct pipe *pipe_handle;
	struct pipe_list *next;
};

struct threadstate	{
	CPU_state cpustate;
	int sleep_state;
	int sleep_count;
	void *entry_fn;
	struct timer_call *idle_timer;
	unsigned long stack;
	unsigned long tmout;
	unsigned long cpu_time;
	char thread_name[NAMEL];
	unsigned long thread_id;
	struct pipe_list *pipe_head;
	struct threadstate *next;
};

struct pipe **get_pipe(unsigned long pid);

int load_thread(CPU_state *state);
int save_thread(CPU_state *state);
int init_cpu_state(CPU_state *state);
void show_state(CPU_state *state);
int set_stack(struct threadstate *state,void *entry,unsigned long stack,void *args,unsigned long signal);
void __cpu(void);
void suspend_all();
void set_page_dir(unsigned long pgdiraddr);
void enable_pg();
void disable_pg();
void init_biosi(void);

void restore_pm();
void prepare_rm();
void halt_cpu();
void halt_sys();
void idle();
void halt();

void setclock(unsigned long hz);

#endif
